package com.sisgesbyte.web.managedBean.mantenimiento.administracion;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
import javax.servlet.http.HttpSession;

import org.primefaces.event.FileUploadEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.event.UnselectEvent;

import com.sisgesbyte.common.ConstantesInternasSistema;
import com.sisgesbyte.common.Validaciones;
import com.sisgesbyte.dao.beanDao.FiltrosBean;
import com.sisgesbyte.dao.beanDao.FiltrosSQLBean;
import com.sisgesbyte.services.administracion.MantenimientoCategoriaProd;
import com.sisgesbyte.services.administracion.MantenimientoMarca;
import com.sisgesbyte.services.administracion.MantenimientoProducto;
import com.sisgesbyte.services.administracion.MantenimientoUnidMedida;
import com.sisgesbyte.services.administracion.bean.CategoriaProdBean;
import com.sisgesbyte.services.administracion.bean.CategoriaProdListaResponse;
import com.sisgesbyte.services.administracion.bean.MarcaBean;
import com.sisgesbyte.services.administracion.bean.MarcaListaResponse;
import com.sisgesbyte.services.administracion.bean.ProductoBean;
import com.sisgesbyte.services.administracion.bean.ProductoListaResponse;
import com.sisgesbyte.services.administracion.bean.UnidMedidaListaResponse;
import com.sisgesbyte.services.administracion.bean.UnidadMedidaBean;
import com.sisgesbyte.services.commonBean.GenericResponse;
import com.sisgesbyte.web.managedBean.common.MantenimientoAbstract;
import com.sisgesbyte.web.managedBean.seguridad.OpcionesControlador;

@ManagedBean
@ViewScoped
public class ProductoMBean extends MantenimientoAbstract implements
		Serializable {

	private static final long serialVersionUID = 1L;

	@EJB
	private MantenimientoProducto mantenimientoProducto;
	@EJB
	private MantenimientoCategoriaProd mantenimientoCategoriaProd;
	@EJB
	private MantenimientoMarca mantenimientoMarca;
	@EJB
	private MantenimientoUnidMedida mantenimientoUnidMedida;
	@Inject
	private Validaciones validaciones;
	@ManagedProperty(value = "#{opcionesControlador}")
	private OpcionesControlador opcionesControlador;
	private FiltrosSQLBean cadenaFiltros;
	private List<ProductoBean> listaProductos;
	private List<ProductoBean> selectedProducto;
	private List<CategoriaProdBean> listaCategoriaProductos;
	private List<MarcaBean> listaMarca;
	private List<UnidadMedidaBean> listaUnidaMedidas;
	private String tipoMantenimiento;
	private String saved;
	private String txtBuscar;

	@PostConstruct
	private void init() {
		saved = "";
		tipoMantenimiento = "";
		txtBuscar = "";
		crearFiltro();
		inicializar();
		listarCategoriaProductos();
		listarMarcas();
		listarUnidadMedidas();
	}

	public OpcionesControlador getOpcionesControlador() {
		return opcionesControlador;
	}

	public void setOpcionesControlador(OpcionesControlador opcionesControlador) {
		this.opcionesControlador = opcionesControlador;
	}

	public List<ProductoBean> getListaProductos() {
		return listaProductos;
	}

	public void setListaProductos(List<ProductoBean> listaProductos) {
		this.listaProductos = listaProductos;
	}

	public List<ProductoBean> getSelectedProducto() {
		return selectedProducto;
	}

	public void setSelectedProducto(List<ProductoBean> selectedProducto) {
		this.selectedProducto = selectedProducto;
	}

	public String getTipoMantenimiento() {
		return tipoMantenimiento;
	}

	public void setTipoMantenimiento(String tipoMantenimiento) {
		this.tipoMantenimiento = tipoMantenimiento;
	}

	public String getSaved() {
		return saved;
	}

	public void setSaved(String saved) {
		this.saved = saved;
	}

	public String getTxtBuscar() {
		return txtBuscar;
	}

	public void setTxtBuscar(String txtBuscar) {
		this.txtBuscar = txtBuscar;
	}

	public FiltrosSQLBean getCadenaFiltros() {
		return cadenaFiltros;
	}

	public void setCadenaFiltros(FiltrosSQLBean cadenaFiltros) {
		this.cadenaFiltros = cadenaFiltros;
	}

	public List<CategoriaProdBean> getListaCategoriaProductos() {
		return listaCategoriaProductos;
	}

	public void setListaCategoriaProductos(
			List<CategoriaProdBean> listaCategoriaProductos) {
		this.listaCategoriaProductos = listaCategoriaProductos;
	}

	public List<MarcaBean> getListaMarca() {
		return listaMarca;
	}

	public void setListaMarca(List<MarcaBean> listaMarca) {
		this.listaMarca = listaMarca;
	}

	public List<UnidadMedidaBean> getListaUnidaMedidas() {
		return listaUnidaMedidas;
	}

	public void setListaUnidaMedidas(List<UnidadMedidaBean> listaUnidaMedidas) {
		this.listaUnidaMedidas = listaUnidaMedidas;
	}

	@Override
	public void inicializar() {
		try {
			ProductoListaResponse response = mantenimientoProducto.listaProductos(ObtenerIdTransaccion(), cadenaFiltros);
			if (Integer.valueOf(response.getCodigoRespuesta()) > -1) {
				listaProductos = response.getListaProductos();
			} else {
				System.out.println("No se encontro Data " + response.getMensajeRespuesta());
			}
		} catch (Exception e) {
			System.out.println("Ocurrio un error al cargar Lista " + e);
		}
	}
	public void listarCategoriaProductos(){
		try {
			FiltrosSQLBean filtroSQL = new FiltrosSQLBean();
			filtroSQL.setCampoOrden("nombre");
			filtroSQL.setTipoOrden("asc");
			CategoriaProdListaResponse response = mantenimientoCategoriaProd.listaCategoriasProducto(ObtenerIdTransaccion(), filtroSQL);
			if (Integer.valueOf(response.getCodigoRespuesta()) > -1) {
				this.listaCategoriaProductos = response.getListaCategoriaProductos();
			} else {
				System.out.println("No se encontro Data " + response.getMensajeRespuesta());
			}
		} catch (Exception e) {
			System.out.println("Ocurrio un error al cargar Lista " + e);
		}
	}
	
	public void listarMarcas(){
		try {
			FiltrosSQLBean filtroSQL = new FiltrosSQLBean();
			filtroSQL.setCampoOrden("marca");
			filtroSQL.setTipoOrden("asc");
			MarcaListaResponse response = mantenimientoMarca.listaMarcas(ObtenerIdTransaccion(), filtroSQL);
			if (Integer.valueOf(response.getCodigoRespuesta()) > -1) {
				this.listaMarca = response.getListaMarca();
			} else {
				System.out.println("No se encontro Data " + response.getMensajeRespuesta());
			}
		} catch (Exception e) {
			System.out.println("Ocurrio un error al cargar Lista " + e);
		}
	}
	
	public void listarUnidadMedidas(){
		try {
			FiltrosSQLBean filtroSQL = new FiltrosSQLBean();
			filtroSQL.setCampoOrden("descripcion");
			filtroSQL.setTipoOrden("asc");
			UnidMedidaListaResponse response = mantenimientoUnidMedida.listaUnidMedida(ObtenerIdTransaccion(), filtroSQL);
			if (Integer.valueOf(response.getCodigoRespuesta()) > -1) {
				this.listaUnidaMedidas = response.getListaUnidaMedidas();
			} else {
				System.out.println("No se encontro Data " + response.getMensajeRespuesta());
			}
		} catch (Exception e) {
			System.out.println("Ocurrio un error al cargar Lista " + e);
		}
	}
	
	@Override
	public void unSelect(UnselectEvent event) {
		opcionesControlador.habilitarControles(selectedProducto.size());
	}

	@Override
	public void checkSelect(SelectEvent event) {
		opcionesControlador.habilitarControles(selectedProducto.size());
	}

	@Override
	public void seleccionarItem(SelectEvent event) {
		opcionesControlador.habilitarControles(selectedProducto.size());
	}

	@Override
	public void dobleSelect(SelectEvent event) {
		List<ProductoBean> selected = new ArrayList<ProductoBean>();
		selected.add((ProductoBean) event.getObject());
		setSelectedProducto(selected);
		setSaved("");
		opcionesControlador.habilitarControles(selectedProducto.size());
		setTipoMantenimiento(ConstantesInternasSistema.TIPO_MANTENIMIENTO_UPDATE);
	}

	@Override
	public void nuevoItem() {
		setSaved("");
		limpiarFormulario();
		setTipoMantenimiento(ConstantesInternasSistema.TIPO_MANTENIMIENTO_NUEVO);
	}

	@Override
	public void editItem() {
		setSaved("");
		setTipoMantenimiento(ConstantesInternasSistema.TIPO_MANTENIMIENTO_UPDATE);
	}

	@Override
	public void updateInsertItem() {
		if (tipoMantenimiento
				.equalsIgnoreCase(ConstantesInternasSistema.TIPO_MANTENIMIENTO_NUEVO)) {
			guardarItem();
		}
		if (tipoMantenimiento
				.equalsIgnoreCase(ConstantesInternasSistema.TIPO_MANTENIMIENTO_UPDATE)) {
			modificarItem();
		}
	}

	@Override
	public String ObtenerIdTransaccion() {
		FacesContext fCtx = FacesContext.getCurrentInstance();
		HttpSession session = (HttpSession) fCtx.getExternalContext()
				.getSession(false);
		String sessionId = session.getId().replace(".undefined", "");
		return sessionId;
	}

	@Override
	public void guardarItem() {
		GenericResponse response = null;
		try {
			for (ProductoBean bean : listaSeleccionados(selectedProducto)) {
				response = mantenimientoProducto.nuevoProducto( ObtenerIdTransaccion(), bean);
				if (response.getCodigoRespuesta().equals( ConstantesInternasSistema.CODIGO_EXITO)) {
					setSaved(ConstantesInternasSistema.SAVED_ITEM_OK);
					System.out.println("Se registro Correctamente");
				} else {
					setSaved(ConstantesInternasSistema.SAVED_ITEM_ERROR);
					System.out.println("Hubo un error al Registrar " + response.getCodigoRespuesta() + " - " + response.getMensajeRespuesta());
				}
			}
			limpiarFormulario();
			inicializar();
		} catch (Exception e) {
			setSaved(ConstantesInternasSistema.SAVED_ITEM_ERROR);
			System.out.println("Error en el proceso " + e);
		}
	}

	@Override
	public void modificarItem() {
		GenericResponse response = null;
		try {
			for (ProductoBean bean : listaSeleccionados(selectedProducto)) {
				response = mantenimientoProducto.editarProducto( ObtenerIdTransaccion(), bean);
				if (response.getCodigoRespuesta().equals( ConstantesInternasSistema.CODIGO_EXITO)) {
					setSaved(ConstantesInternasSistema.SAVED_ITEM_OK);
					System.out.println("Se Acualizo correctamente");
				} else {
					setSaved(ConstantesInternasSistema.SAVED_ITEM_ERROR);
					System.out.println("Hubo un Error al Actualizar de BD " + response.getCodigoRespuesta() + " - " + response.getMensajeRespuesta());
				}
			}
			inicializar();
		} catch (Exception e) {
			System.out.println("Error en el proceso " + e);
		}
	}

	@Override
	public void eliminarItem() {
		GenericResponse response = null;
		try {
			for (ProductoBean bean : selectedProducto) {
				response = mantenimientoProducto.deleteProducto(
						ObtenerIdTransaccion(), bean.getId());
				if (response.getCodigoRespuesta().equals(
						ConstantesInternasSistema.CODIGO_EXITO)) {
					System.out.println("Se elimino Correctamente");
				} else {
					System.out.println("No se pudo Eliminar de BD "
							+ response.getCodigoRespuesta() + " - "
							+ response.getMensajeRespuesta());
				}
			}
			inicializar();
			opcionesControlador.desactivarControles();
		} catch (Exception e) {
			System.out.println("Hubo un error al tratar de Eliminar " + e);
		}
	}

	@Override
	public void actualizarEstado() {
		GenericResponse response = null;
		try {
			for (ProductoBean bean : listaSeleccionados(listaProductos)) {
				response = mantenimientoProducto.editarProducto(ObtenerIdTransaccion(), bean);
				if (response.getCodigoRespuesta().equals(ConstantesInternasSistema.CODIGO_EXITO)) {
					System.out.println("Se Acualizo correctamente");
				} else {
					System.out.println("No se pudo actualizar el Item con codigo "+ bean.getId());
				}
			}
			inicializar();
		} catch (Exception e) {
			System.out.println("Hubo un error al actualizar el estado");
		}
	}

	@Override
	public void limpiarFormulario() {
		List<ProductoBean> listaBean = new ArrayList<ProductoBean>();
		ProductoBean bean = new ProductoBean();
		bean.setImagen(ConstantesInternasSistema.IMAGEN_DEFAULT);
		listaBean.add(bean);
		setSelectedProducto(listaBean);
	}

	/*
	 * Metodo para recorrer y validar los tipos de campos seleccionados
	 */
	public List<ProductoBean> listaSeleccionados(List<ProductoBean> listaRequest) {
		List<ProductoBean> response = new ArrayList<ProductoBean>();
		for (ProductoBean listaBean : listaRequest) {
			ProductoBean bean = new ProductoBean();
			bean.setActive(listaBean.getActive());
			bean.setCategoria_producto_id(listaBean.getCategoria_producto_id());
			bean.setCod_barra(validaciones.validarCamposString(listaBean
					.getCod_barra()));
			bean.setCod_prod(validaciones.validarCamposString(listaBean
					.getCod_prod()));
			bean.setId(listaBean.getId());
			bean.setImagen(validaciones
					.validarCamposString(ConstantesInternasSistema.IMAGEN_DEFAULT));
			bean.setMarca_id(listaBean.getMarca_id());
			bean.setObservacion(validaciones.validarCamposString(listaBean
					.getObservacion()));
			bean.setPeso(listaBean.getPeso());
			bean.setPrecio_promedio(listaBean.getPrecio_promedio());
			bean.setProducto(validaciones.validarCamposString(listaBean
					.getProducto()));
			bean.setUnidad_medida_id(listaBean.getUnidad_medida_id());
			bean.setUnidadesxcaja(listaBean.getUnidadesxcaja());
			response.add(bean);
		}
		return response;
	}

	// metodo para subir archivos
	public void subirArchivo(FileUploadEvent event) {

		try {
			File folder = new File(ConstantesInternasSistema.RUTA_IMAGEN_PRODUCTOS);
			InputStream inputStream = event.getFile().getInputstream();
			OutputStream out = new FileOutputStream(new File(folder, event.getFile().getFileName()));

			int read = 0;
			byte[] bytes = new byte[1024];
			while ((read = inputStream.read(bytes)) != -1) {
				out.write(bytes, 0, read);
			}
			inputStream.close();
			out.flush();
			out.close();
			
			for (ProductoBean bean : selectedProducto) {
				actualizarImagenProducto(bean.getId(),event.getFile().getFileName());
			}
			

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void actualizarImagenProducto(int idProducto,String imagen) {
		GenericResponse response = null;
		try {
			ProductoBean producto = new ProductoBean();
			producto.setId(idProducto);
			producto.setImagen(imagen);
			response = mantenimientoProducto.actualizarImagenProducto( ObtenerIdTransaccion(), producto);
			if (response.getCodigoRespuesta().equals( ConstantesInternasSistema.CODIGO_EXITO)) {
				inicializar();
				System.out.println("Imagen Se Acualizo correctamente");
			} else {
				System.out.println("No se pudo actualizar la Imagen " + response.getMensajeRespuesta());
			}
		} catch (Exception e) {
			System.out.println("Hubo un error al actualizar el estado");
		}
	}

	@Override
	public void crearFiltro() {
		FiltrosSQLBean filtroSQL = new FiltrosSQLBean();
		try {
			if (getTxtBuscar() != null
					&& getTxtBuscar().toString().length() > 0) {

				List<Object> valores = new ArrayList<>();
				List<FiltrosBean> filtro = new ArrayList<FiltrosBean>();
				FiltrosBean listaCampo = new FiltrosBean();
				List<String> campo = new ArrayList<String>();
				campo.add("p.id");
				campo.add("cp.nombre");
				campo.add("m.marca");
				campo.add("p.cod_prod");
				campo.add("p.cod_barra");
				campo.add("p.producto");
				campo.add("p.precio_promedio");
				listaCampo.setCampos(campo);
				listaCampo.setOperador("like");
				filtro.add(listaCampo);
				filtroSQL.setListaFiltros(filtro);
				valores.add("%" + getTxtBuscar() + "%");
				filtroSQL.setListaValores(valores);

			} else {
				filtroSQL.setCampoOrden("p.id");
				filtroSQL.setTipoOrden("desc");
			}
			setCadenaFiltros(filtroSQL);
			inicializar();
			opcionesControlador.habilitarControles(0);
		} catch (Exception e) {
			System.out.println("Error al crear filtro " + e);
			filtroSQL.setCampoOrden("p.id");
			filtroSQL.setTipoOrden("desc");
		}
	}

}
